package com.djx.provider.demo;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 多线程实现
 * @author dingjunxiong
 */
public class MyThread {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ImplRunnable runnable = new ImplRunnable();
        for (int i = 0; i < 10; i++) {
            //继承Thread多线程
//            ExtendsThread thread = new ExtendsThread();
//            thread.num = i;
//            thread.start();
            //实现Runnable多线程
//            new Thread(runnable).start();
            //实现Callable多线程
            Callable callable = new ImplCallable();
            FutureTask futureTask = new FutureTask(callable);
            new Thread(futureTask).start();
            System.out.println("futureTask get : " + futureTask.get());
        }
        System.out.println("main print:" + Thread.currentThread().getName());
    }

    /**
     * 继承Thread多线程
     *
     * 每次创建一个新的线程，都要新建一个Thread子类的对象
     * 　　启动线程，new Thread子类（）.start（）
     * 　　创建线程实际调用的是父类Thread空参的构造器
     */
    static class ExtendsThread extends Thread {
        public Integer num;

        @Override
        public void run() {
            Map map = new HashMap(16);
            map.put(num, num);
            System.out.println("ExtendsThread print:" + Thread.currentThread().getName() + " | map:" + map);
        }
    }

    /**
     * 实现Runnable多线程
     *
     * 不论创建多少个线程，只需要创建一个Runnable接口实现类的对象
     * 　　启动线程，new Thread（Runnable接口实现类的对象）.start()
     *  　 创建线程调用的是Thread类Runable类型参数的构造器
     */
    static class ImplRunnable implements Runnable {
        public Integer num = 0;

        @Override
        public void run() {
            Map map = new HashMap(16);
            Integer count = num++;
            map.put(count, count);
            System.out.println("ImplRunnable print:" + Thread.currentThread().getName() + " | map:" + map);
        }
    }

    /**
     * 实现Callable多线程
     *
     * 每次创建一个新的线程，都要创建一个新的Callable接口的实现类、
     * 　　如何启动线程？
     * 　　　　（1）创建一个Callable接口的实现类的对象
     * 　　　　（2）创建一个FutureTask对象，传入Callable类型的参数
     * 　　　　　　　　public FutureTask(Callable<V> callable){……}
     * 　　　　（3）调用Thread类重载的参数为Runnable的构造器创建Thread对象
     * 　　　　　　　　将FutureTask作为参数传递
     * 　　　　　　　　public class FutureTask<V> implements RunnableFuture<V>
     * 　　　　　　　　public interface RunnableFuture<V> extends Runnable, Future<V>
     * 　　如何获取返回值？
     * 　　　　调用FutureTask类的get()方法
     */
    static class ImplCallable implements Callable {

        @Override
        public Object call() throws Exception {
            int result = 0;
            for (int i = 0; i < 10; i++) {
                result += i;
            }
            System.out.println("ImplCallable print:" + Thread.currentThread().getName());
            return result;
        }
    }

}
